from utils import log_info, log_exception, log_error, log_debug
from typing import List, Dict, Any
from .base_dao import BaseDAO
from models.question import Question
from dao.db_pool import get_db_pool

"""
    题目表数据访问对象

    id 主键
    J 编号1
    P 编号2
    I 编号3，J、P、I三个字段结合唯一确定一道题
    Q 题干
    T 答案，如A，ABC等
    A 选项A
    B 选项B
    C 选项C
    D 选项D
    F 图片（可选），base64编码，以data:image/png;base64,开头
    LA =1 表示存在于A类题库
    LB =1 表示存在于B类题库
    LC =1 表示存在于C类题库
    type 题型，1表示单选题，2表示多选题
"""

class QuestionDAO(BaseDAO[Question]):
    """题目表数据访问对象"""

    def __init__(self):
        """
        初始化QuestionDAO
        """
        super().__init__(Question)



    def _get_table_name(self) -> str:
        """获取表名"""
        return "questions"

    def _get_primary_key(self) -> str:
        """获取主键名"""
        return "id"

    def get_by_type(self, type_value: int) -> List[Question]:
        """
        根据类型整数获取题目
        :param type_value: 题目类型整数
        :return: 题目实体列表
        """
        sql = "SELECT * FROM questions WHERE type = ?"
        params = (type_value,)
        return self._execute_query(sql, params)



    def get_random_questions(self, type_value: int, count: int) -> List[Question]:
        """
        随机获取指定类型的题目
        :param type_value: 题目类型整数
        :param count: 获取的题目数量
        :return: 随机题目实体列表
        """
        sql = "SELECT * FROM questions WHERE type = ? ORDER BY RANDOM() LIMIT ?"
        params = (type_value, count)
        return self._execute_query(sql, params)

    def search(self, keyword: str) -> List[Question]:
        """
        搜索题目
        :param keyword: 搜索关键词
        :return: 匹配的题目实体列表
        """
        # 在题目内容和选项中搜索关键词
        sql = "SELECT * FROM questions WHERE Q LIKE ? OR A LIKE ? OR B LIKE ? OR C LIKE ? OR D LIKE ?"
        params = (f"%{keyword}%", f"%{keyword}%", f"%{keyword}%", f"%{keyword}%", f"%{keyword}%")
        return self._execute_query(sql, params)

    def get_questions_by_category(self, category: str) -> List[Question]:
        """
        根据类别获取题目
        :param category: 类别，如'A', 'B', 'C'
        :return: 题目实体列表
        """
        # 确定对应的类别字段
        category_field = {"A": "LA", "B": "LB", "C": "LC"}.get(category.upper(), "LA")
        sql = f"SELECT * FROM questions WHERE {category_field} = 1"
        return self._execute_query(sql)

    def get_random_questions_by_category_and_type(self, category: str, type_value: int, count: int) -> List[Question]:
        """
        根据类别和题型随机获取指定数量的题目
        :param category: 类别，如'A', 'B', 'C'
        :param type_value: 题目类型，1表示单选题，2表示多选题
        :param count: 获取的题目数量
        :return: 随机题目实体列表
        """
        # 确定对应的类别字段
        category_field = {"A": "LA", "B": "LB", "C": "LC"}.get(category.upper(), "LA")
        sql = f"SELECT * FROM questions WHERE {category_field} = 1 AND type = ? ORDER BY RANDOM() LIMIT ?"
        params = (type_value, count)
        return self._execute_query(sql, params)

    def batch_insert(self, questions: List[Dict[str, Any]]) -> bool:
        """
        批量插入题目
        :param questions: 题目字典列表
        :return: 是否插入成功
        """
        if not questions:
            return True

        try:
            db_pool = get_db_pool()
            conn = db_pool.get_connection()
            if not conn:
                log_error("无法从连接池获取数据库连接")
                return False

            cursor = conn.cursor()

            # 准备插入数据
            insert_data = []
            for q in questions:
                # 处理空值
                for key in q:
                    if q[key] is None:
                        q[key] = ''

                insert_data.append((
                    q.get('J', ''), q.get('P', ''), q.get('I', ''), q.get('Q', ''),
                    q.get('T', ''), q.get('A', ''), q.get('B', ''), q.get('C', ''),
                    q.get('D', ''), q.get('F', ''), q.get('LA', 0), q.get('LB', 0),
                    q.get('LC', 0), q.get('type', 0)
                ))

            # 执行批量插入
            cursor.executemany('''
                INSERT INTO questions (J, P, I, Q, T, A, B, C, D, F, LA, LB, LC, type)
                VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
            ''', insert_data)

            conn.commit()
            conn.close()
            log_debug(f"批量插入成功，共{len(questions)}条记录")
            return True

        except Exception as e:
            log_exception(f"批量插入题目时发生异常: {str(e)}")
            return False